package com.sghd.football.module.game.service.thread;

import com.sghd.football.module.game.service.core.Desk;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.concurrent.DelayQueue;

/**
 * \* Created with 王创辉.
 * \* Date: 2018/5/21
 * \* Time: 15:10
 * \* @desc:
 */

@Component
public class ThreadService {
    private static final Logger logger = LoggerFactory.getLogger(ThreadService.class);
    /** 当前值等于玩家人数就是一个玩家一个线程*/
    @Value("${sys.thread.core:4}")
    private int threadCore;
    /**线程组按desk分线程(懒加载)*/
    private RoomThread[] threads;
    /** 匹配线程*/
    private RoomThread matchThread;

    /** 超时分发队列*/
    private DelayQueue<TaskItem> overtimeQueue;

    @PostConstruct
    void init() {
        threads = new RoomThread[threadCore];
        matchThread = new RoomThread("MATCH_THREAD");
        matchThread.start();
        overtimeQueue = new DelayQueue<>();
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (!Thread.interrupted()) {
                    try {
                        final TaskItem work = overtimeQueue.take();
                        int type = work.getType();
                        switch (type) {
                            case TaskItem.DESK:
                                Task task = work.getContent();
                                Desk desk = work.getDesk();//桌子
                                if (desk == null) {
                                    logger.error("desk is null:[{}]", task.getClass());
                                    continue;
                                } else {
                                    submit(desk.getId(), () -> task.run(desk, work.getEnd()));
                                }
                                break;
                            case TaskItem.MATCH:
                                Task taskMatch = work.getContent();
                                submit(() -> taskMatch.run(null, work.getEnd()));
                                break;
                        }
                    } catch (Exception e) {
                        logger.error("超时任务分发线程发生异常...", e);
                    }
                }
            }
        }, "超时任务分发总线程");
        thread.setDaemon(true);
        thread.start();
    }

    //@PreDestroy
    void destory() {
        for (RoomThread thread : threads) {
            thread.stopTask();
        }
    }

    public void add(TaskItem taskItem) {
        overtimeQueue.add(taskItem);
    }

    public void submit(int id, Runnable runnable) {
        int index = id % threads.length;
        RoomThread thread = threads[index];
        if (thread == null || thread.isInterrupted()) {
            thread = new RoomThread(index);
            threads[index] = thread;
            thread.start();
        }
        thread.addTask(runnable);
    }

    /**匹配线程*/
    public void submit(Runnable runnable) {
        matchThread.addTask(runnable);
    }

    public void close() {
        matchThread.stopTask();//停止匹配线程
        logger.error("MATCH_THREAD CLOSE SUCCESS");
        for (int i = 0; i < threads.length; i++) {//停止工作线程
            RoomThread thread = threads[i];
            thread.stopTask();
            logger.error("WORK_THREAD CLOSE SUCCESS");
        }
    }
}